import React from 'react'
import appStyles from './App.module.css'
import lessStyles from './Test.module.less'
// CSS in js
import { AppWrapper, AppProps } from './style'
// 引用添加类名库
import classNames from 'classnames'

// 编写一个组件：
class App extends React.Component {
  constructor() {
    super()

    this.state = {
      // 受控组件：
      inputValue: '默认值，且无法直接输入',
      couldChangeValue: '默认值，可以直接输入修改',

      // CSS in js
      bgc: 'pink',
      size: 20
    }
  }

  changeInputValue(e) {
    this.setState({
      inputValue: e.target.value,
      couldChangeValue: e.target.value
    })
  }

  // 2、执行 render 函数
  render() {
    // P5受控组件、P6编写CSS、（P5的高阶组件没学、过渡动画没学，可以说全部没学）、
    const { inputValue, couldChangeValue, bgc, size } = this.state

    return (
      <div>
        {/* 受控组件 */}
        {/* 
          发生情况：由于 react 里面没有双向绑定，因此当表单框里面的默认 value 值绑定了 this.state 里的值，就无法再次输入修改
          改变方法：绑定 value 的同时，加上 onChange 事件，即手动双向绑定，类似 vue 当中的 :value + @input
        */}
        <h4>受控组件</h4>
        <div>
          普通输入框：
          <input
            type="text"
            onChange={(e) => this.changeInputValue(e)}
          />
        </div>
        <div>
          不可直接输入的输入框（会报警告）：
          <input
            type="text"
            value={inputValue}
          />
        </div>
        <div>
          可以直接输入的输入框：
          <input
            type="text"
            value={couldChangeValue}
            onChange={(e) => this.changeInputValue(e)}
          />
        </div>
        {/* React 中编写 CSS */}
        {/* 
          1、内联样式：
          优点：
            1、内联样式：样式之间不会有冲突
            2、可以动态获取当前 state 中的状态
          缺点：
            1、写法上都需要驼峰标识
            2、大量代码，很混乱
            3、某些样式无法编写（比如伪类/伪元素）

          2、CSS modules：
          CSS modules 并不是 React 特有的解决方案，而是所有使用了类似于 webpack 配置的环境下都可以使用
          如果想要在其他项目中使用它，那么需要我们自己来配置，比如配置 webpack.config.js 的 modules: true 等
          用法：
            1、首先将 css 文件名命名为：名字.module.css
            2、在组件当中引入：import 定义名字 from '路径'
            3、在 className 中使用 定义名字.定义的类名即可
          缺点：
            1、引用的类名，不能使用连接符（.aaa-bbb），但是可以使用对象的另一种引入方式：定义名['定义类名']
            2、不方便动态来修改某些样式，依然需要使用内联样式的方式

          3、CSS in js
          虽然 CSS 预处理器也具备某些能力，但是获取动态状态依然是一个不好处理的点
          用法：
            1、下载 styled-components 库
            2、在一个 js 文件中编写 CSS 代码，详情见 style.js 文件
            3、在组件中引入编写 css 的文件，例如：import { AppWrapper } from './style'
            4、将一个最外层盒子用第三步里定义的名字作为标签名包裹，例如：<AppWrapper></AppWrapper>
            5、在该标签名里正常写 HTML ，className 正常加就好（写 css 的 js 文件中存在即可）
        */}
        <h4>React 中编写 CSS</h4>
        <p>1、CSS modules：</p>
        <div className={appStyles.title}>这是使用 CSS module 方式引用的样式</div>
        <div className={appStyles['title-a']}>这是使用 CSS module 方式引用的样式</div>

        <p>2、Less modules（暂未生效，需要配置，但没成功）：</p>
        <div className={lessStyles.font}>这是使用 Less module 方式引用的样式</div>

        <p>3、CSS in js：</p>
        <AppWrapper>
          <div className="inJs">这是使用 CSS in js 方法使用样式</div>
          <span className="test">这是使用 CSS in js 方法使用样式</span>
        </AppWrapper>
        {/* 可以通过传属性值的方式将组件定义的值传给该 js 文件 */}
        <AppProps
          bgc={bgc}
          size={size}
        >
          <span className="appPropsClass">通过动态传值修改样式</span>
        </AppProps>

        {/* 使用库添加类名： */}
        <p className={classNames('aaa', { bbb: true, ccc: false })}>我是使用库来添加的类名，请查看我的结构1</p>
        <p className={classNames(['aaa', { bbb: true, ccc: false }])}>我是使用库来添加的类名，请查看我的结构2</p>
      </div>
    )
  }
}

export default App
